/**
 * @file STL_Text.h
 * @author Derek Liu (yjkhtddx@sina.com)
 * @brief 
 * @version 0.1
 * @date 2020-09-15
 * 
 * @copyright Copyright Sci-Tech Laboratories (c) 2020
 * 
 */

#ifndef __STL_URL_H__
#define __STL_URL_H__

#include <string>
#include <vector>
#include <map>
#include "STL_Tools.h"

namespace STL
{
    class STL_URL
    {
    public:
        typedef struct UrlInfo_t
        {
            std::string protocol;  // 协议
            std::string username;  // 用户名
            std::string password;  // 密码
            std::string host;      // 主机地址
            uint16_t port;         // 端口
            std::string path;      // 路径
            std::string parameter; // 参数
            std::string query;     // 查询字符串
            std::string fragment;  // 片段
            UrlInfo_t()
            {
                this->protocol = "";  // 协议
                this->username = "";  // 用户名
                this->password = "";  // 密码
                this->host = "";      // 主机地址
                this->port = 0;       // 端口
                this->path = "";      // 路径
                this->parameter = ""; // 参数
                this->query = "";     // 查询字符串
                this->fragment = "";  // 片段
            }
            UrlInfo_t(std::string protocol, std::string host, uint16_t port, std::string path)
            {
                this->protocol = protocol; //协议
                this->host = host;         // 主机地址
                this->port = port;         // 端口
                this->path = path;         // 路径
            }
        } UrlInfo;

    public:
        //<protocol>://[<username>:<password>@]<host>[:<port>][/path][;params][?<query>][#fragment]
        static STL_URL::UrlInfo parseUrl(std::string url);
        static std::string genUrl(STL_URL::UrlInfo info);

    public:
        static uint16_t defaultPort(std::string protocol);
        static std::string UrlEncode(const std::string str);
        static std::string UrlDecode(const std::string str);
        static std::string genQueryWithUrlEncode(std::map<std::string, std::string> queryMap)
        {
            std::string ret;
            // Content-Type: application/x-www-form-urlencoded
            for (auto it = queryMap.begin(); it != queryMap.end(); ++it)
            {
                if (it->first.empty())
                {
                    continue;
                }
                if (it != queryMap.begin())
                {
                    ret = ret + "&";
                }
                ret = ret + it->first + "=" + STL_URL::UrlEncode(it->second);
            }
            return ret;
        }
        static std::string genQueryWithUrlEncodeRemoveEmpty(std::map<std::string, std::string> queryMap)
        {
            std::string ret;
            // Content-Type: application/x-www-form-urlencoded
            for (auto it = queryMap.begin(); it != queryMap.end(); ++it)
            {
                if (it->first.empty() || it->second.empty())
                {
                    continue;
                }
                if (it != queryMap.begin())
                {
                    ret = ret + "&";
                }
                ret = ret + it->first + "=" + STL_URL::UrlEncode(it->second);
            }
            return ret;
        }
    };

} // namespace STL

#endif /* __STL_URL_H__ */
